package com.douqu.game.core.entity.ext.data.boon;

import com.bean.core.buffer.ByteBuffer;
import com.bean.core.util.TimeUtils;
import com.douqu.game.core.config.*;
import com.douqu.game.core.config.challenge.InstanceConfig;
import com.douqu.game.core.config.challenge.LevelConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.e.*;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.db.InstanceDB;
import com.douqu.game.core.entity.db.InstanceListDB;
import com.douqu.game.core.entity.db.LevelDB;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.data.BaseData;
import com.douqu.game.core.entity.world.WorldAuctionBean;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author wangzhenfei
 * 2017-10-28 16:06
 * 福利
 */
public class BonusData extends BaseData {

    //固定福利

    /**
     * 缓存限时促销推送信息
     **/
    public int saleId;
    /**
     * 首冲礼包是否领取过
     **/
    private boolean isFistRechargeReceive;
    /**
     * 签到福利  签到的id
     **/
    private int signRewardIndex; //对应每日签到配置的下标
    private List<Integer> signRecordList;
    private long lastSignTime;
    private long lastResetTime;// 上次重置时间
    private int reissueTimes;//补签次数
    /**
     * 登录福利   登录天数
     **/
    private int loginTimesByDay;
    private long updateTime;
    private List<Integer> loginRewardRecord;//登录奖励的领取记录
    /**
     * 各种基金类型的map   <基金类型， 领取记录>
     **/
    private Map<Integer, List<Integer>> fundMap;
    /**
     * 新区基金登录天数
     */
    private int loginTimesByDayForNewFund;
    private long lastDailyRechargeReceiveTime;
    /**
     * boss掉落物品出售后的分红奖励
     */
    private int auctionReward;
    /**
     * 玩家拍卖记录
     */
    private Map<Integer, AuctionRecord> records;
    /**
     * 限时活动
     **/
    private Map<Integer, TimeLimitedData> activityRecord;
    /**
     * 限时促销 key：促销类型
     */
    private Map<Integer, List<FlashSaleRecord>> flashSaleRecordMap;
    /**
     * 消耗钻石的缓存 每次玩家登录的时候从数据库获取 玩家花费的时候加入
     * 这个字段不做任何持久化操作
     */
    private Map<E_QueryRechargeCountType, Integer> diamondsCache;

    private Player player;

    public BonusData(Player player) {
        this.player = player;
        signRecordList = new CopyOnWriteArrayList<>();
        loginRewardRecord = new CopyOnWriteArrayList<>();
        fundMap = new ConcurrentHashMap<>();
        records = new ConcurrentHashMap<>();
        activityRecord = new ConcurrentHashMap<>();
        flashSaleRecordMap = new ConcurrentHashMap<>();
        initDiamondsCache();
    }

    /**
     * 初始化diamondsCache
     */
    private void initDiamondsCache() {
        diamondsCache = new ConcurrentHashMap<>();
        diamondsCache.put(E_QueryRechargeCountType.DAILY, 0);
        //diamondsCache.put(E_QueryRechargeCountType.WEEKLY,0);
        diamondsCache.put(E_QueryRechargeCountType.DEFINE, 0);
    }

    @Override
    public void init() {
        loginTimesByDay = 1;
        lastResetTime = DataFactory.currentTime;
        updateTime = DataFactory.currentTime;
        // 初始化限时促销基础数据
        FlashSaleConfig.initOrReset(flashSaleRecordMap, true);
    }

    @Override
    public void checkInit() {
        if (flashSaleRecordMap.isEmpty()) {
            init();
        }
    }

    @Override
    public void reset() {
        if (!TimeUtils.isToday(updateTime)) {
            updateTime = DataFactory.currentTime;

            checkAddLoginDay();
            FlashSaleConfig.initOrReset(flashSaleRecordMap, false);
        }

        checkTimeActivity();
        checkSignReset();
        checkRecords();
        if (!CoreUtils.isTodayByOffset(lastDailyRechargeReceiveTime, DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_FRESH_TIMES_HOUR)) {
            fundMap.remove(SGCommonProto.E_FUND_TYPE.FUND_TYPE_DAILY_TOTAL_RECHARGE_VALUE);
            fundMap.remove(SGCommonProto.E_FUND_TYPE.FUND_TYPE_DAILY_TOTAL_CONSUME_VALUE);
        }
    }

    private void checkSignReset() {
        /**
         * 不在一个月份重置
         */
        if (!TimeUtils.getFormatTime(lastResetTime, "yyyyMM").equals(TimeUtils.getFormatTime(DataFactory.currentTime, "yyyyMM"))) {
            signRecordList.clear();
            lastResetTime = DataFactory.currentTime;
            signRecordList.clear();
            reissueTimes = 0;
            DailySignRewardConfig dailySignRewardConfig = DataFactory.getInstance().getGameObject(DataFactory.DAILY_SIGN_KEY, 1);
            signRewardIndex++;
            signRewardIndex = signRewardIndex % dailySignRewardConfig.reward.length;
        }
    }

    /**
     * 检测是否增加登录天数
     */
    private void checkAddLoginDay() {
        loginTimesByDay++;
        if (isFundBuy(SGCommonProto.E_FUND_TYPE.FUND_TYPE_NEW_SERVER)) {
            loginTimesByDayForNewFund++;
        }
    }

    /**
     * 检查已经结束的拍卖信息来清除  每日凌晨四点
     */
    public void checkRecords() {
        Iterator<Map.Entry<Integer, AuctionRecord>> it = records.entrySet().iterator();
        WorldAuctionBean bean = null;
        Map<Integer, WorldAuctionBean> auctions = WorldInfoFactory.getInstance().getWorldAuctionData().getAuctionMap();
        Map.Entry<Integer, AuctionRecord> entry = null;
        while (it.hasNext()) {
            entry = it.next();
            bean = auctions.get(entry.getKey());
            if (bean == null) {
                //清除记录
                it.remove();
                continue;
            }
            if (bean.getState() == E_AuctionStatus.END_THE_AUCTION.getCode()
                    && !TimeUtils.isToday(entry.getValue().getAuctionTime())) {
                //清除记录
                it.remove();
                //删除数据
                auctions.remove(bean);
            }
        }
    }

    /**
     * 清空玩家的本周分红数据  每周日的24点调用
     */
    public void initAuctionReward() {
        auctionReward = 0;
    }

    public void addDiamondsCache(int value) {
        if (value < 0) {
            value = -value;
        } else {
            LogUtils.error("增加钻石 不计入消耗 value : " + value);
            return;
        }
        for (Map.Entry<E_QueryRechargeCountType, Integer> entry : diamondsCache.entrySet()) {
            diamondsCache.put(entry.getKey(), entry.getValue() + value);
        }
    }

    /**
     * 清除玩家缓存的钻石消耗
     * 这个方法只处理在线的玩家
     */
    public void resetDiamondsCache() {
        diamondsCache.put(E_QueryRechargeCountType.DAILY, 0);
        //如果跳出活动日期 清空
        TimeLimitedActivitiesConfig config =
                TimeLimitedActivitiesConfig.getCurrentConfigByType(E_TimeLimitActivityType.TOTAL_DIAMONDS);
        //如果不在时间范围内就不为空
        if (config == null) {
            diamondsCache.put(E_QueryRechargeCountType.DEFINE, 0);
        }
    }

    /**
     * 限时活动合法性检测,删除过期数据
     */
    private void checkTimeActivity() {
        TimeLimitedActivitiesConfig config = null;
        for (Integer key : activityRecord.keySet()) {
            config = DataFactory.getInstance().getGameObject(DataFactory.TIME_LIMIT_ACTIVITY_KEY, key);
            if (config == null || !config.isTimeInForReceiver()) {
                activityRecord.remove(key);
            }
        }

    }

    /**
     * 限时活动红点检测
     *
     * @return
     */
    public boolean redTimeActivity() {
        TimeLimitedActivitiesConfig config = TimeLimitedActivitiesConfig.getCurrentConfigByType(E_TimeLimitActivityType.TOTAL_RECHARGE);
        if (config != null) {
            int rechargeCount = player.getRechargeData().getRechargeCount(E_QueryRechargeCountType.DEFINE.getCode());
            for (GoodsData goodsData : config.reward) {
                //如果充值金额 大于 且为领取的出现红点
                if (rechargeCount >= goodsData.extraValue[0]
                        && (activityRecord.get(config.id) == null ? true : !activityRecord.get(config.id).getRecordList().contains(goodsData.extraValue[0]))) {
                    return true;
                }
            }
        }

        config = TimeLimitedActivitiesConfig.getCurrentConfigByType(E_TimeLimitActivityType.TOTAL_DIAMONDS);
        if (config != null) {
            int diamonds = diamondsCache.get(E_QueryRechargeCountType.DEFINE);
            for (GoodsData goodsData : config.reward) {
                if (diamonds >= goodsData.extraValue[0]
                        && (activityRecord.get(config.id) == null ? true : !activityRecord.get(config.id).getRecordList().contains(goodsData.extraValue[0]))) {
                    return true;
                }
            }
        }

        return false;
    }

    @Override
    public void checkReset() {
        reset();
    }

    public boolean checkLoginBonus() {
        //累计登录奖励没领取
        if(!CoreUtils.isFunctionUnLock(FunctionFactory.LOGIN_REWARD, player))
            return false;

        List<LoginTimesBonusConfig> dataList = DataFactory.getInstance().getDataList(DataFactory.LOGIN_TIMES_REWARD_KEY);
        for (LoginTimesBonusConfig config : dataList) {
            if (config.id <= loginTimesByDay) {
                if (!loginRewardRecord.contains(config.id)) {
                    return true;
                }
            } else {
                break;
            }
        }
        return false;
    }

    public boolean hasRedPointRemind() {
        //今日没有签到
        if (!TimeUtils.isToday(lastSignTime)) {
            return true;
        }

        //今日有月卡奖励未领取
        RechargeConfig rechargeConfig = null;
        int mouthCardNum = 0;
        for (Map.Entry<Integer, RechargeRecordData.MouthCardRecord> entry : player.getRechargeData().getRechargeRecordMap().entrySet()) {
            rechargeConfig = DataFactory.getInstance().getGameObject(DataFactory.RECHARGE_KEY, entry.getKey());
            if (rechargeConfig.type == E_RechargeGoodsType.MOUTH_CARD.getCode() || rechargeConfig.type == E_RechargeGoodsType.WEEK_CARD.getCode()) {
                mouthCardNum++;
                if (entry != null && DataFactory.currentTime < entry.getValue().getEndTime() && //未过期
                        !TimeUtils.isToday(entry.getValue().getLastRewardTime())) { //今日未领取
                    return true;
                }
            }
        }

        if (mouthCardNum != 2) {
            return true;
        }

        //开服基金未购买
        if (!isFundBuy(SGCommonProto.E_FUND_TYPE.FUND_TYPE_OPEN)) {
            return true;
        }

        List<FundRewardConfig> rewardConfigs = DataFactory.getInstance().getDataList(DataFactory.FUND_REWARD_KEY);
        for (FundRewardConfig config : rewardConfigs) {
            if (config.type == SGCommonProto.E_FUND_TYPE.FUND_TYPE_OPEN.getNumber()) {
                if (player.getLv() < config.minlv) {
                    return false;
                } else {
                    if (!isFundRewardReceive(SGCommonProto.E_FUND_TYPE.FUND_TYPE_OPEN, config.id)) {
                        return true;
                    }
                }
            }


        }

        //新区基金未购买
        if (!isFundBuy(SGCommonProto.E_FUND_TYPE.FUND_TYPE_NEW_SERVER)) {
            return true;
        }

        //未充值，累计充值加红点
        if (player.getVipExp() == 0) {
            return true;
        }

        for (FundRewardConfig config : rewardConfigs) {
            if (config.type == SGCommonProto.E_FUND_TYPE.FUND_TYPE_NEW_SERVER.getNumber()) {
                if (loginTimesByDayForNewFund < config.minlv) {
                    return false;
                } else {
                    if (!isFundRewardReceive(SGCommonProto.E_FUND_TYPE.FUND_TYPE_NEW_SERVER, config.id)) {
                        return true;
                    }
                }
            } else if (config.type == SGCommonProto.E_FUND_TYPE.FUND_TYPE_TOTAL_RECHARGE.getNumber()) {
                if (player.getVipExp() / 10 < config.minlv) {
                    return false;
                } else {
                    if (!isFundRewardReceive(SGCommonProto.E_FUND_TYPE.FUND_TYPE_TOTAL_RECHARGE, config.id)) {
                        return true;
                    }
                }
            }
        }


        return false;
    }


    @Override
    public void writeTo(ByteBuffer buffer) {
        buffer.writeBoolean(isFistRechargeReceive);
        buffer.writeByte(signRewardIndex);

        buffer.writeShort(signRecordList.size());
        for (Integer id : signRecordList) {
            buffer.writeInt(id);
        }

        buffer.writeLong(lastSignTime);
        buffer.writeLong(lastResetTime);
        buffer.writeShort(reissueTimes);

        buffer.writeShort(loginTimesByDay);
        buffer.writeLong(updateTime);

        buffer.writeShort(loginRewardRecord.size());
        for (Integer id : loginRewardRecord) {
            buffer.writeInt(id);
        }

        buffer.writeShort(fundMap.size());
        for (Map.Entry<Integer, List<Integer>> entry : fundMap.entrySet()) {
            buffer.writeInt(entry.getKey());
            buffer.writeShort(entry.getValue().size());
            for (Integer integer : entry.getValue()) {
                buffer.writeInt(integer);
            }
        }

        buffer.writeBoolean(true);

        buffer.writeInt(auctionReward);

        buffer.writeShort(records.size());
        for (Map.Entry<Integer, AuctionRecord> entry : records.entrySet()) {
            buffer.writeInt(entry.getKey());
            entry.getValue().writeTo(buffer);
        }

        buffer.writeLong(lastDailyRechargeReceiveTime);

        buffer.writeBoolean(true);

        buffer.writeInt(loginTimesByDayForNewFund);
        buffer.writeBoolean(false);
        //++++++++++++++++++++++++++++++20180508

        buffer.writeShort(activityRecord.size());
        for (Map.Entry<Integer, TimeLimitedData> entry : activityRecord.entrySet()) {
            buffer.writeInt(entry.getKey());
            entry.getValue().writeTo(buffer);
        }

        buffer.writeShort(flashSaleRecordMap.size());
        for (Map.Entry<Integer, List<FlashSaleRecord>> entry : flashSaleRecordMap.entrySet()) {
            buffer.writeShort(entry.getValue().size());
            buffer.writeInt(entry.getKey());
            for (FlashSaleRecord fsr : entry.getValue()) {
                fsr.writeTo(buffer);
            }
        }

        buffer.writeBoolean(false);
    }

    @Override
    public void loadFrom(ByteBuffer buffer) {
        isFistRechargeReceive = buffer.readBoolean();
        signRewardIndex = buffer.readByte();

        int size = buffer.readShort();
        for (int i = 0; i < size; i++) {
            signRecordList.add(buffer.readInt());
        }
        lastSignTime = buffer.readLong();
        lastResetTime = buffer.readLong();
        reissueTimes = buffer.readShort();
        loginTimesByDay = buffer.readShort();
        updateTime = buffer.readLong();

        size = buffer.readShort();
        for (int i = 0; i < size; i++) {
            loginRewardRecord.add(buffer.readInt());
        }

        size = buffer.readShort();
        for (int i = 0; i < size; i++) {
            int key = buffer.readInt();
            int listSize = buffer.readShort();
            List<Integer> list = new CopyOnWriteArrayList<>();
            for (int j = 0; j < listSize; j++) {
                list.add(buffer.readInt());
            }
            fundMap.put(key, list);
        }

        boolean flag = buffer.readBoolean();

        if (flag) {
            auctionReward = buffer.readInt();
            size = buffer.readShort();
            Integer key;
            AuctionRecord auctionRecord;
            for (int i = 0; i < size; i++) {
                key = buffer.readInt();
                auctionRecord = new AuctionRecord();
                auctionRecord.loadFrom(buffer);
                //两件事 1.找到商品确认是否是你拍卖的(在被别人抢了之后已经进行过离线处理) 2商品是否还存在
                if (WorldInfoFactory.getInstance().getWorldAuctionData().getRecord(auctionRecord.getAuctionBeanId()) != null)
                    records.put(key, auctionRecord);
            }
            lastDailyRechargeReceiveTime = buffer.readLong();

            flag = buffer.readBoolean();
            if (flag) {
                loginTimesByDayForNewFund = buffer.readInt();
                buffer.readBoolean();
            }

            //++++++++++++++++++++++20180508
            size = buffer.readShort();
            for (int i = 0; i < size; i++) {
                key = buffer.readInt();
                TimeLimitedData data = new TimeLimitedData(key);
                data.loadFrom(buffer);
                activityRecord.put(key, data);
            }

            size = buffer.readShort();
            for (int i = 0; i < size; i++) {
                int length = buffer.readShort();
                int flashSaleType = buffer.readInt();
                List<FlashSaleRecord> list = new ArrayList<>(length);
                flashSaleRecordMap.put(flashSaleType, list);
                for (int j = 0; j < length; j++) {
                    FlashSaleRecord flashSaleRecord = new FlashSaleRecord();
                    flashSaleRecord.loadFrom(buffer);
                    list.add(flashSaleRecord);
                }
            }
            buffer.readBoolean();
        }
    }


    /**
     * 获取最大的签到天数
     *
     * @return
     */
    public int getMaxSignDay() {
        return signRecordList.size() == 0 ? 0 : signRecordList.get(signRecordList.size() - 1);
    }

    /**
     * 增加签到记录
     *
     * @param day
     * @param timeNow
     */
    public void addSignRecord(int day, long timeNow) {
        if (!signRecordList.contains(day)) {
            signRecordList.add(day);
            this.lastSignTime = timeNow;
        }
    }

    /**
     * 今天是否签到过了
     *
     * @return
     */
    public boolean isSignToday() {
        return TimeUtils.isToday(lastSignTime);
    }

    /**
     * 首冲奖励是否领取过
     *
     * @return
     */
    public boolean isFistRechargeReceive() {
        return isFistRechargeReceive;
    }

    /**
     * 设置首冲奖励已经领取
     *
     * @param isFistRechargeReceive
     */
    public void setFistRechargeReceive(boolean isFistRechargeReceive) {
        this.isFistRechargeReceive = isFistRechargeReceive;
    }

    /**
     * 是否购买了基金
     *
     * @return
     */
    public boolean isFundBuy(SGCommonProto.E_FUND_TYPE fundType) {
        return fundMap.get(fundType.getNumber()) != null;
    }


    /**
     * 清除基金购买记录
     *
     * @return
     */
    public void clearFund(SGCommonProto.E_FUND_TYPE fundType) {
        fundMap.remove(fundType.getNumber());
        return;
    }


    /**
     * 设置基金已购买
     */
    public void buyFund(SGCommonProto.E_FUND_TYPE fundType) {
        if (!isFundBuy(fundType)) {
            if (fundType == SGCommonProto.E_FUND_TYPE.FUND_TYPE_NEW_SERVER) {
                loginTimesByDayForNewFund = 1;
            }
            fundMap.put(fundType.getNumber(), new CopyOnWriteArrayList<>());
        }
    }

    /**
     * 增加基金领取记录
     *
     * @param rewardId
     */
    public void addFundRewardRecord(SGCommonProto.E_FUND_TYPE fundType, int rewardId) {
        if (fundType == SGCommonProto.E_FUND_TYPE.FUND_TYPE_TOTAL_RECHARGE || fundType == SGCommonProto.E_FUND_TYPE.FUND_TYPE_DAILY_TOTAL_RECHARGE
                || fundType == SGCommonProto.E_FUND_TYPE.FUND_TYPE_DAILY_TOTAL_CONSUME) {
            if (fundType == SGCommonProto.E_FUND_TYPE.FUND_TYPE_DAILY_TOTAL_RECHARGE
                    || fundType == SGCommonProto.E_FUND_TYPE.FUND_TYPE_DAILY_TOTAL_CONSUME) {
                lastDailyRechargeReceiveTime = DataFactory.currentTime;
            }

            List<Integer> list = fundMap.get(fundType.getNumber());
            if (list == null) {
                list = new CopyOnWriteArrayList<>();
                fundMap.put(fundType.getNumber(), list);
            }
            list.add(rewardId);
            return;
        }
        if (isFundBuy(fundType)) {
            if (!fundMap.get(fundType.getNumber()).contains(rewardId)) {
                fundMap.get(fundType.getNumber()).add(rewardId);
            }
        }

    }

    /**
     * 基金奖励是否领取
     *
     * @param rewardId
     * @return
     */
    public boolean isFundRewardReceive(SGCommonProto.E_FUND_TYPE fundType, int rewardId) {
        if (isFundBuy(fundType)) {
            return fundMap.get(fundType.getNumber()).contains(rewardId);
        }
        return false;
    }

    /**
     * 累计登陆奖励是否领取
     *
     * @param rewardId
     * @return
     */
    public boolean isLoginTimesRewardReceive(int rewardId) {
        return loginRewardRecord.contains(rewardId);
    }

    /**
     * 累计登陆奖励是否领取
     *
     * @param rewardId
     * @return
     */
    public void addLoginTimesRewardReceive(int rewardId) {
        if (!loginRewardRecord.contains(rewardId)) {
            loginRewardRecord.add(rewardId);
        }
    }


    public int getLoginTimesByDay() {
        return loginTimesByDay;
    }

    public List<Integer> getLoginRewardRecord() {
        return loginRewardRecord;
    }

    /**
     * 获取已经补签的次数
     *
     * @return
     */
    public int getReissueTimes() {
        return reissueTimes;
    }

    public int getLoginTimesByDayForNewFund() {
        return loginTimesByDayForNewFund;
    }

    /**
     * 增加补签的次数
     *
     * @return
     */
    public int addReissueTimes() {
        return ++reissueTimes;
    }

    /**
     * 获取每日签到奖励对应配置表的下标
     *
     * @return
     */
    public int getSignRewardIndex() {
        return signRewardIndex;
    }


    public List<Integer> getSignRecordList() {
        return signRecordList;
    }

    public int getMaxSignRecord() {
        int size = signRecordList.size();
        return size == 0 ? 0 : signRecordList.get(size - 1);
    }

    public List<Integer> getFundReceiverRecord(SGCommonProto.E_FUND_TYPE type) {
        List<Integer> list = fundMap.get(type.getNumber());
        return list == null ? new ArrayList<>() : list;
    }

    public Map<Integer, AuctionRecord> getRecords() {
        return records;
    }

    public void setRecords(Map<Integer, AuctionRecord> records) {
        this.records = records;
    }

    public int getAuctionReward() {
        return auctionReward;
    }

    public void setAuctionReward(int auctionReward) {
        this.auctionReward = auctionReward;
    }

    public void addAuctionReward(int addNumber) {
        auctionReward += addNumber;
    }

    public Integer getDiamondsCacheDaily() {
        if (diamondsCache.get(E_QueryRechargeCountType.DAILY) == null) {
            diamondsCache.put(E_QueryRechargeCountType.DAILY, 0);
        }
        return diamondsCache.get(E_QueryRechargeCountType.DAILY);
    }

    public Integer getDiamondsCacheDefine() {
        if (diamondsCache.get(E_QueryRechargeCountType.DEFINE) == null) {
            diamondsCache.put(E_QueryRechargeCountType.DEFINE, 0);
        }
        return diamondsCache.get(E_QueryRechargeCountType.DEFINE);
    }

    public void setDiamondsCache(Map<E_QueryRechargeCountType, Integer> diamondsCache) {
        this.diamondsCache = diamondsCache;
    }

    /************限时活动****************/
    public Map<Integer, TimeLimitedData> getActivityRecord() {
        return activityRecord;
    }

    /**
     * 限时活动记录是否存在
     *
     * @param activityId
     * @param recordId
     * @return
     */
    public boolean hasReceiveActivityReward(int activityId, int recordId) {
        TimeLimitedData data = activityRecord.get(activityId);
        if (data == null) {
            data = new TimeLimitedData(activityId);
            activityRecord.put(activityId, data);
        }
        return data.containsRecord(recordId);
    }

    /**
     * 增加限时活动记录
     *
     * @param activityId
     * @param recordId
     * @return
     */
    public void addActivityReward(int activityId, int recordId) {
        TimeLimitedData data = activityRecord.get(activityId);
        if (data == null) {
            data = new TimeLimitedData(activityId);
            activityRecord.put(activityId, data);
        }
        if (!data.containsRecord(recordId)) {
            data.addRecord(recordId);
        }
    }

    /***********************************限时促销************************************/
    /**
     * 获取所有已开放的限时促销
     *
     * @return
     */
    public Map<Integer, Integer> getInTimeFlashSaleRecord() {
        Map<Integer, Integer> temp = new HashMap<>();
        for (List<FlashSaleRecord> list : flashSaleRecordMap.values()) {
            for (FlashSaleRecord fsr : list) {
                isInCD(fsr);
                if (fsr.isOpen) {
                    temp.put(fsr.id, (int) (fsr.endTime - DataFactory.currentTime));
                }
            }
        }
        return temp;
    }

    /**
     * 某个限时活动是否在有效期内,此方法仅供充值检测
     *
     * @param linkId
     * @return
     */
    public boolean isInTime(int linkId) {
        for (List<FlashSaleRecord> list : flashSaleRecordMap.values()) {
            for (FlashSaleRecord fsr : list) {
                if (fsr.id != linkId) {
                    continue;
                }
                isInCD(fsr);
                if (fsr.isOpen) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean levelIsPass(int instanceID, PlayerController playerController) {
        // 是否第一次弹出
        LevelConfig lc = DataFactory.getInstance().getGameObject(DataFactory.LEVEL_KEY, instanceID);
        if (lc == null) {
            return false;
        }
        InstanceConfig ic = DataFactory.getInstance().getGameObject(DataFactory.INSTANCE_KEY, lc.getInstanceId());
        if (ic == null) {
            return false;
        }
        InstanceListDB ildb = playerController.getPlayer().getChallengeInfo().getInstanceData().getInstanceListDB(ic.type);
        if (ildb == null) {
            return false;
        }
        InstanceDB idb = ildb.getInstanceMap().get(ic.id);
        if (idb == null) {
            return false;
        }
        LevelDB levelDB = idb.getLevelMap().get(instanceID);
        if (levelDB == null) {
            return false;
        }
        return levelDB.getMaxStars() > 0 ? true : false;
    }

    /**
     * 检测限时促销是否可以开放
     *
     * @param playerController
     * @param type
     * @return
     */
    public FlashSaleRecord check(PlayerController playerController, E_FlashSaleType type) {
        List<FlashSaleRecord> list = flashSaleRecordMap.get(type.getCode());
        if (list != null) {
            for (FlashSaleRecord fsr : list) {
                if (!fsr.isFinish && !fsr.isOpen) {
                    // 验证条件是否满足
                    FlashSaleConfig
                            flashSaleConfig = DataFactory.getInstance().getGameObject(DataFactory.FLASH_SALE_KEY, fsr.id);
                    if (flashSaleConfig == null) {
                        continue;
                    }

                    if (type == E_FlashSaleType.PASS_INSTANCE) {
                        if (!levelIsPass(flashSaleConfig.condition, playerController)) {
                            continue;
                        }
                    }

                    if (playerController.getPlayer().getLv() < flashSaleConfig.level[0] || playerController.getPlayer().getLv() > flashSaleConfig.level[1]) {
                        // 等级不符合条件
                        continue;
                    }

                    int currentHour = CoreUtils.getHour();
                    if (currentHour < flashSaleConfig.openTime[0] || currentHour > flashSaleConfig.openTime[1]) {
                        // 时间点不符合条件
                        continue;
                    }
                    // 开启此限时折扣
                    fsr.open(flashSaleConfig.times, CoreUtils.getNowTime() + flashSaleConfig.showTime * 1000);
                    return fsr;
                }
            }
        }
        return null;
    }

    /**
     * 购买限时促销
     *
     * @param flashSaleID
     */
    public void buyFlashSale(int flashSaleID) {
        flashSaleRecordMap.values().forEach(list -> list.stream().filter(fsr -> fsr.id == flashSaleID && fsr.isOpen).forEach(fsr -> FlashSaleConfig.findNext(fsr)));
    }

    public void consumeItemFishFlashSale(PlayerController playerController, int flashSaleID) {
        flashSaleRecordMap.values().forEach(list -> list.stream().filter(fsr -> fsr.id == flashSaleID && fsr.isOpen).forEach(fsr -> {
            FlashSaleConfig flashSaleConfig = DataFactory.getInstance().getGameObject(DataFactory.FLASH_SALE_KEY, flashSaleID);
            if (flashSaleConfig == null) {
                return;
            }

            if (flashSaleConfig.rechargeId == 0) {
                // 道具是否足够
                BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
                for (GoodsData goods : flashSaleConfig.cost) {
                    if (bagInfo.getGoodsCount(goods.type, goods.id) < goods.value) {
                        playerController.sendWarn(WordFactory.ASSET_NOT_ENOUGH, goods.id);
                        return;
                    }
                }
                // 扣除资源
                bagInfo.subGoods(flashSaleConfig.cost);

                // 增加新的资源
                bagInfo.addGoods(flashSaleConfig.goods);

                FlashSaleConfig.findNext(fsr);
            }
        }));
    }

    /**
     * 检测是否还在CD中
     *
     * @param fsr
     */
    private void isInCD(FlashSaleRecord fsr) {
        if (fsr.isOpen && CoreUtils.getNowTime() >= fsr.endTime) {
            // 时间到，次数减1，并查找下一级配置
            FlashSaleConfig.findNext(fsr);
        }
    }
}
